package com.example.mybatismappingtest.handle;

import com.mysql.cj.jdbc.exceptions.OperationNotSupportedException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.*;
import java.util.HashMap;
import java.util.Map;

//自定义TypeHandler
public class ExtraMapTypeHandler extends BaseTypeHandler<Map<String, Object>> {
    //定义一个前缀常量
    private static final String PREFIX = "extra_";
    //定义一个方法，用于判断列名是否以前缀开头
    private boolean isExtraColumn(String columnName) {
        return columnName.startsWith(PREFIX);
    }
    //定义一个方法，用于去掉列名的前缀
    private String removePrefix(String columnName) {
        return columnName.substring(PREFIX.length());
    }
    //重写setNonNullParameter方法，将Map转换为JSON字符串
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Map<String, Object> parameter, JdbcType jdbcType) throws SQLException {
        throw new OperationNotSupportedException("不支持对扩展进行setNonNullParameter操作");
    }
    //重写getNullableResult方法，将ResultSet中的以extra_开头的字段放到Map中
    @Override
    public Map<String, Object> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        //创建一个Map对象
        Map<String, Object> map = new HashMap<>();
        //获取ResultSet的元数据
        ResultSetMetaData metaData = rs.getMetaData();
        //获取列的数量
        int columnCount = metaData.getColumnCount();
        //遍历所有的列
        for (int i = 1; i <= columnCount; i++) {
            //获取列名
            String colName = metaData.getColumnName(i);
            //判断列名是否以extra_开头
            if (isExtraColumn(colName)) {
                //去掉前缀
                String key = removePrefix(colName);
                //获取列的值
                Object value = rs.getObject(i);
                //放到Map中
                map.put(key, value);
            }
        }
        //返回Map
        return map;
    }

    @Override
    public Map<String, Object> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        //获取列名
        String columnName = rs.getMetaData().getColumnName(columnIndex);
        //调用getNullableResult方法
        return getNullableResult(rs, columnName);
    }

    @Override
    public Map<String, Object> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        //获取列名
        String columnName = cs.getMetaData().getColumnName(columnIndex);
        //调用getNullableResult方法
        return getNullableResult(cs, columnName);    }

    //重写getResult方法，根据列索引获取值
    @Override
    public Map<String, Object> getResult(ResultSet rs, int columnIndex) throws SQLException {
        //获取列名
        String columnName = rs.getMetaData().getColumnName(columnIndex);
        //调用getNullableResult方法
        return getNullableResult(rs, columnName);
    }
    //重写getResult方法，根据存储过程获取值
    @Override
    public Map<String, Object> getResult(CallableStatement cs, int columnIndex) throws SQLException {
        //获取列名
        String columnName = cs.getMetaData().getColumnName(columnIndex);
        //调用getNullableResult方法
        return getNullableResult(cs, columnName);
    }

    private Map<String, Object> getNullableResult(CallableStatement cs, String columnName) throws SQLException {
        //创建一个Map对象
        Map<String, Object> map = new HashMap<>();
        //获取ResultSet的元数据
        ResultSetMetaData metaData = cs.getMetaData();
        //获取列的数量
        int columnCount = metaData.getColumnCount();
        //遍历所有的列
        for (int i = 1; i <= columnCount; i++) {
            //获取列名
            String colName = metaData.getColumnName(i);
            //判断列名是否以extra_开头
            if (isExtraColumn(colName)) {
                //去掉前缀
                String key = removePrefix(colName);
                //获取列的值
                Object value = cs.getObject(i);
                //放到Map中
                map.put(key, value);
            }
        }
        //返回Map
        return map;
    }
}
